//cardGameFunctions.h
/********************************************************************************
*																				*
*	Author:			Jared Szechy												*
*	Assignment:		Assignment 8												*
*	Class:			CPS-151														*
*	Instructor:		V. Starkley													*
*	Due Date:		November 7													*
*																				*
*	This program simulates the card game: war.									*
*																				*
********************************************************************************/

#include <iostream>
#include <fstream>
using namespace std;
#include "deck.h"
#include "Countedq.h"
#include "cardGameFunctions.h"

int war(ostream& fout, CountedQue<Card>& hand1, CountedQue<Card>& hand2, Card card1, Card card2, CountedQue<Card>& outcome, int& wars);
//pre: none
//post: if player one wins war returns 1, if player 2 wins war returns 2, delt card stored in outcome, number of wars is also incremented accordingly

int main()
{
	Deck theDeck;
	CountedQue<Card> hand1, hand2, outcome;
	Card player1card, player2card, tempCard;
	int round;
	int warWin;
	int longestGame = 0, shortestGame = 5000, largestWars = 0, smallestWars = 0, games;
	int wars, totWars= 0, totRounds = 0;
	double avgGame, avgWars;

	//declare output stream, deletes file contents upon opening
	ofstream fout ("game_stats.txt", ios::trunc);
	if(fout.fail())
	{
		cout << "ERROR: Could not open game_stats.txt" << endl;
		system("pause");
		exit(1);
	}
	
	//determine number of games to simulate
	cout << "How many games of war do you wish to simulate? ";
	cin >> games;

    for(int curGame = 1; curGame <= games; curGame++)
	{
		fout << "Game " << curGame << endl;
		round = 1;
		wars = 0;

		//shuffle deck
		theDeck.Shuffle();

		//deal 26 cards to each player
		for(int i = 0; i < 26; i++)
		{
			Deal(theDeck, hand1, 1);
			Deal(theDeck, hand2, 1);
		}

		//loop for every round
		while(!hand1.IsEmpty() && !hand2.IsEmpty() && round <= 5000)
		{
			//play a card from each hand
			fout << "Round " << round << ":" << endl;
			fout << "Player1\t\tPlayer2" << endl;
			hand1.Dequeue(player1card);
			hand2.Dequeue(player2card);
			fout << player1card << "\t\t" << player2card << endl;

			//determine who won
			if(player1card.getValue() > player2card.getValue())
			{
				fout << "Player 1 wins match" << endl;
				hand1.Enqueue(player1card);
				hand1.Enqueue(player2card);
			}
			if(player2card.getValue() > player1card.getValue())
			{
				fout << "Player 2 wins match" << endl;
				hand2.Enqueue(player2card);
				hand2.Enqueue(player1card);
			}

			//if values are the same call war function
			if(player2card.getValue() == player1card.getValue())
			{
				fout << "WAR!" << endl;
				warWin = war(fout, hand1, hand2, player1card, player2card, outcome, wars);
				if(warWin == 1)
				{
					while(!outcome.IsEmpty())
					{
						outcome.Dequeue(tempCard);
						hand1.Enqueue(tempCard);
					}
				}
				if(warWin == 2)
				{
					while(!outcome.IsEmpty())
					{
						outcome.Dequeue(tempCard);
						hand2.Enqueue(tempCard);
					}
				}
			}
			fout << endl;

			//every 5 rounds display summary
			if (round % 5 == 0)
			{
				fout << "Status Report:" << endl;
				fout << "Player 1 has " << hand1.LengthIs() << " cards remaining." << endl;
				fout << "Player 2 has " << hand2.LengthIs() << " cards remaining." << endl;
				fout << endl;
			}
			if (round % 100 == 0)
			{
				shuffle(hand1);
				shuffle(hand2);
			}
			round++;
		}

		//determine who won the game
		if(hand1.IsEmpty())
			fout << "Player 2 won the game!" << endl << endl;
		else if(hand2.IsEmpty())
			fout << "Player 1 won the game!" << endl << endl;
		else
			fout << "The game is a draw" << endl << endl;

		//reset hands and deck
		hand1.MakeEmpty();
		hand2.MakeEmpty();
		theDeck.ResetDeck();
		
		//calculate stats
		if(round - 1 < shortestGame)
			shortestGame = round - 1;
		if(round - 1 > longestGame)
			longestGame = round - 1;
		totRounds = totRounds + round - 1;

		if(wars < smallestWars || smallestWars == 0)
			smallestWars = wars;
		if(wars > largestWars)
			largestWars = wars;
		totWars = totWars + wars;
	}

	avgGame = totRounds / games;
	avgWars = totWars / games;

	//output stats
	fout << "Shortest Game: " << shortestGame << " rounds." << endl;
	fout << "Longest Game: " << longestGame << " rounds." << endl;
	fout << "Average number of rounds: " << avgGame << endl;
	fout << endl;
	fout << "Smallest number of wars: " << smallestWars << endl;
	fout << "Largest number of wars: " << largestWars << endl;
	fout << "Average number of wars: " << avgWars << endl;

	fout.close();

	cout << "Simulation complete, results stored in output file." << endl;
	system("pause");
	return 0;
}

int war(ostream& fout, CountedQue<Card>& hand1, CountedQue<Card>& hand2, Card card1, Card card2, CountedQue<Card>& outcome, int& wars)
{
	bool won = false;
	bool go1 = true, go2 = true;
	Card tempCard1, tempCard2;

	outcome.Enqueue(card1);
	outcome.Enqueue(card2);

	while (!won)
	{
		wars++;
		for (int i = 0; i < 3; i++)
		{
			if(!hand1.IsEmpty())
			{
				hand1.Dequeue(card1);
				outcome.Enqueue(card1);
			}
			else
				go1 = false;
			if(!hand2.IsEmpty())
			{
				hand2.Dequeue(card2);
				outcome.Enqueue(card2);
			}
			else
				go2 = false;
		}

		if(!hand1.IsEmpty())
			hand1.Dequeue(card1);
		else
			go1 = false;
		if(!hand2.IsEmpty())
			hand2.Dequeue(card2);
		else
			go2 = false;

		if (go1 && go2)
		{
			
			fout << "\tPlayer1\t\tPlayer2" << endl;
			fout << '\t' << card1 << "\t\t" << card2 << endl;
			if(card1.getValue() > card2.getValue())
			{
				fout << "\tPlayer 1 won the war!" << endl;
				outcome.Enqueue(card1);
				outcome.Enqueue(card2);
				won = true;
				return 1;
			}
			if(card2.getValue() > card1.getValue())
			{
				fout << "\tPlayer 2 won the war!" << endl;
				outcome.Enqueue(card1);
				outcome.Enqueue(card2);
				won = true;
				return 2;
			}
			
			outcome.Enqueue(card1);
			outcome.Enqueue(card2);
			if(!hand1.IsEmpty() && !hand2.IsEmpty())
				fout << "The war continues..." << endl;
		}
		else
		{
			if(hand1.IsEmpty())
				return 2;
			if(hand2.IsEmpty())
				return 1;
		}
	}
}




